<template>
  <el-select
    v-model="selectedValue"
    :multiple="multiple"
    :filterable="true"
    :remote="true"
    :remote-method="handleRemoteSearch"
    :loading="loading"
    :placeholder="placeholder"
    :clearable="clearable"
    @change="handleChange"
    @clear="handleClear"
    @visible-change="handleVisibleChange"
  >
    <el-option
      v-for="item in options"
      :key="getOptionKey(item)"
      :label="getOptionLabel(item)"
      :value="getOptionValue(item)"
      :disabled="getOptionDisabled(item)"
    />

    <!-- 加载更多提示 -->
    <div v-if="hasMore" class="load-more-tip" @click="loadMore">
      <span v-if="!loadingMore">点击加载更多</span>
      <span v-else>加载中...</span>
    </div>

    <!-- 无数据提示 -->
    <div v-if="!loading && options.length === 0" class="no-data-tip">
      暂无数据
    </div>
  </el-select>
</template>

<script setup>
import { ref, watch, onMounted, computed } from "vue";

// 定义 Props
const props = defineProps({
  modelValue: {
    type: [String, Number, Array],
    default: ""
  },
  multiple: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: "请选择"
  },
  clearable: {
    type: Boolean,
    default: true
  },
  remoteMethod: {
    type: Function,
    required: true
  },
  debounce: {
    type: Number,
    default: 300
  },
  immediate: {
    type: Boolean,
    default: false
  },
  optionConfig: {
    type: Object,
    default: () => ({
      key: "id",
      label: "name",
      value: "id",
      disabled: "disabled"
    })
  },
  defaultParams: {
    type: Object,
    default: () => ({})
  }
});

// 定义 Emits
const emit = defineEmits(["update:modelValue", "change", "clear"]);

// 响应式数据
const selectedValue = ref(props.modelValue);
const options = ref([]);
const loading = ref(false);
const loadingMore = ref(false);
const hasMore = ref(true);
const searchKeyword = ref("");
const currentPage = ref(1);
const pageSize = ref(20);
let timeoutId = null;

// 计算属性
const loadedCount = computed(() => options.value.length);

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedValue.value = newVal;
  }
);

// 获取选项键值
const getOptionKey = (item) => {
  return item[props.optionConfig.key] || item.id;
};

const getOptionLabel = (item) => {
  return item[props.optionConfig.label] || item.name;
};

const getOptionValue = (item) => {
  return item[props.optionConfig.value] || item.id;
};

const getOptionDisabled = (item) => {
  return item[props.optionConfig.disabled] || false;
};

// 远程搜索方法（带防抖）
const handleRemoteSearch = (query) => {
  searchKeyword.value = query;
  currentPage.value = 1;
  hasMore.value = true;

  if (timeoutId) {
    clearTimeout(timeoutId);
  }

  timeoutId = setTimeout(() => {
    fetchData(query, 1);
  }, props.debounce);
};

// 加载更多
const loadMore = () => {
  if (loadingMore.value || !hasMore.value) return;

  currentPage.value += 1;
  loadingMore.value = true;
  fetchData(searchKeyword.value, currentPage.value, true);
};

// 获取数据
const fetchData = async (keyword, page = 1, isLoadMore = false) => {
  if (!isLoadMore) {
    loading.value = true;
  }

  try {
    const params = {
      keyword: keyword || "",
      page,
      pageSize: pageSize.value,
      ...props.defaultParams
    };

    const result = await props.remoteMethod(params);

    if (result && Array.isArray(result.list)) {
      if (isLoadMore) {
        options.value = [...options.value, ...result.list];
      } else {
        options.value = result.list;
      }

      // 判断是否还有更多数据
      hasMore.value =
        result.list.length >= pageSize.value &&
        (result.total === undefined || options.value.length < result.total);
    } else {
      // 兼容直接返回数组的情况
      const data = Array.isArray(result) ? result : [];
      if (isLoadMore) {
        options.value = [...options.value, ...data];
      } else {
        options.value = data;
      }
      hasMore.value = data.length >= pageSize.value;
    }
  } catch (error) {
    console.error("远程搜索失败:", error);
    if (!isLoadMore) {
      options.value = [];
    }
  } finally {
    loading.value = false;
    loadingMore.value = false;
  }
};

// 处理选择变化
const handleChange = (value) => {
  emit("update:modelValue", value);
  emit("change", value);
};

// 处理清空
const handleClear = () => {
  emit("clear");
};

// 处理下拉框显示/隐藏
const handleVisibleChange = (visible) => {
  if (visible && props.immediate && options.value.length === 0) {
    fetchData("", 1);
  }
};

// 重置搜索
const resetSearch = () => {
  searchKeyword.value = "";
  currentPage.value = 1;
  hasMore.value = true;
  options.value = [];
};

// 重新加载数据
const reload = () => {
  resetSearch();
  fetchData(searchKeyword.value, 1);
};

// 暴露方法给父组件
defineExpose({
  resetSearch,
  reload
});

onMounted(() => {
  if (props.immediate) {
    fetchData("", 1);
  }
});
</script>

<style scoped>
.load-more-tip {
  padding: 8px 16px;
  text-align: center;
  color: #409eff;
  cursor: pointer;
  font-size: 12px;
  border-top: 1px solid #e4e7ed;
}

.load-more-tip:hover {
  background-color: #f5f7fa;
}

.no-data-tip {
  padding: 8px 16px;
  text-align: center;
  color: #909399;
  font-size: 12px;
}
</style>
